#include "ResourcesDecode.h"
#include "Utility/Utility.h"
#include "xxtea.h"

ResourcesDecode *ResourcesDecode::m_resourcesDecode = 0;

ResourcesDecode::ResourcesDecode(void)
{
	m_xxteaEnabled = true;
	m_xxteaKey = 0;
	m_xxteaSign = 0;
}


ResourcesDecode::~ResourcesDecode(void)
{
}


ResourcesDecode *ResourcesDecode::sharedDecode()
{
	if(m_resourcesDecode == 0)
	{
		m_resourcesDecode = new ResourcesDecode();
	}

	return m_resourcesDecode;
}

void ResourcesDecode::setXXTeaKey(const char *xxteaKey, int xxteaKeyLen, const char *xxteaSign, int xxteaSignLen)
{
	if(xxteaKey && xxteaKeyLen && xxteaSign && xxteaKeyLen)
	{
		m_xxteaKey = (char*)malloc(xxteaKeyLen);
		memset(m_xxteaKey, 0, xxteaKeyLen+1);
		memcpy(m_xxteaKey, xxteaKey, xxteaKeyLen);
		m_xxteaKeyLen = xxteaKeyLen;

		m_xxteaSign = (char*)malloc(xxteaSignLen+1);
		memset(m_xxteaSign, 0, xxteaSignLen+1);
		memcpy(m_xxteaSign, xxteaSign, xxteaSignLen);
		m_xxteaSignLen = xxteaSignLen;
	}
}

void ResourcesDecode::cleanupXXTEAKeyAndSign()
{
	if(m_xxteaKey)
	{
		free(m_xxteaKey);
		m_xxteaKey = 0;
	}
	if(m_xxteaSign)
	{
		free(m_xxteaSign);
		m_xxteaSign = 0;
	}
}

void *ResourcesDecode::decodeData(unsigned char *buf, long *pSize)
{
	unsigned char* buffer = NULL;  
	ResourcesDecode* decode = ResourcesDecode::sharedDecode();  
	bool isXXTEA = decode && decode->m_xxteaEnabled;  

	int size = *pSize;
	for (unsigned int i = 0; isXXTEA && i < decode->m_xxteaSignLen && i < size; ++i)  
	{  
		isXXTEA = buf[i] == decode->m_xxteaSign[i];  
	}  

	if (isXXTEA)  
	{  
		//decrypt XXTEA  
		size_t  len = 0;  
		buffer = (unsigned char*)xxtea_decrypt(buf+decode->m_xxteaSignLen, (size_t)size -(size_t)decode->m_xxteaSignLen, (unsigned char*)decode->m_xxteaKey, &len);  
		free(buf);  
		buf = NULL;  
		size = len;  
	}  
	else  
	{  
		buffer = buf;  
	}  

	if (pSize)  
	{  
		*pSize = size;  
	}  
	return buffer;  
}